﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

namespace mrp16062010
{
    class OptimumGeriYukle
    {
        public string Id { get; set; }
        public static int nesneSayac;
        Cizelge cizelge;
        Rota.RotaParcasi rota;
        List<Rota.Operasyon> operasyon;
        DateTime baslangicTarihi;
        DateTime bitisTarihi;
        public bool IsYuklendi = false;
        int grupNo;
        private Tarih yuklemeTarihi = new Tarih();

        public Tarih YuklemeTarihi
        {
            get { return yuklemeTarihi; }
            set { yuklemeTarihi = value; }
        }

        private Siparis siparisBilgi;

        public Siparis SiparisBilgi
        {
            get { return siparisBilgi; }
            set { siparisBilgi = value; }
        }

        public OptimumGeriYukle(Rota.RotaParcasi gelenParca)
        {
            Cizelge yeniCizelge = new Cizelge();
            Siparis yeniSiparis = new Siparis(999, gelenParca, 1, new Tarih(new DateTime(2010, 1, 1, 8, 0, 0), new DateTime(2010, 10, 31, 17, 30, 0)));

            siparisBilgi = yeniSiparis;
            yuklemeTarihi.BitisTarihi = yeniSiparis.TarihBilgisi.BitisTarihi;
            mrp16062010.Yukle.sayac++;
            grupNo = mrp16062010.Yukle.sayac;
            cizelge = yeniCizelge;
            rota = gelenParca;
            baslangicTarihi = yeniSiparis.TarihBilgisi.BaslangicTarihi;
            bitisTarihi = yeniSiparis.TarihBilgisi.BitisTarihi;
            OptimumHesapla();
            int toplamAdet = gelenParca.TumSiralamalar.Count;
            int alinacakAdet = Convert.ToInt32(((double)((double)Ayarlar.Nesne.OptimumYuklemeYuzdesi / (double)100)) * toplamAdet);
            gelenParca.TumSiralamalar = gelenParca.TumSiralamalar.Take(alinacakAdet).ToList();
        }

        private void OptimumHesapla()
        {
            rota.TumSiralamalar = new List<Rota.SiralamaBilgileri>();
            Rota.Karmala kar = new Rota.Karmala(rota);
            if (kar.anaListe != null)
            {
                foreach (List<Rota.OptimumSiralama> sira in kar.anaListe)
                {
                    Rota.SiralamaBilgileri bilgi = new Rota.SiralamaBilgileri();
                    bilgi.Siralama = sira;
                    DateTime? sonTarih = OptimumYukle(rota, bitisTarihi, 0, sira);
                    if (sonTarih.HasValue)
                    {
                        baslangicTarihi = sonTarih.Value;
                        IsYuklendi = true;
                        bilgi.Sure = bitisTarihi.Subtract(baslangicTarihi);
                        //cizelge.Kaydet(null, grupNo);
                        yuklemeTarihi.BaslangicTarihi = sonTarih.Value;
                    }
                    else
                    {
                        IsYuklendi = false;
                    }
                    cizelge.GeriAl(null, grupNo);
                    rota.TumSiralamalar.Add(bilgi);
                }
            }
            rota.TumSiralamalar = rota.TumSiralamalar.Where(x => x.Sure.HasValue).OrderBy(x => x.Sure).ToList();
        }

        private DateTime? OptimumYukle(Rota.RotaParcasi rotaParcasi, DateTime gelenTarih, int recDerinlik, List<Rota.OptimumSiralama> siralamalar)
        {
            DateTime sonTarih = DateTime.FromBinary(gelenTarih.ToBinary());
            foreach (Rota.Operasyon op in rotaParcasi.OperasyonList.Reverse<Rota.Operasyon>())
            {
                IsParcasi donenIsparcasi = Cizelge.ParcaEkle(cizelge, op, null, sonTarih, recDerinlik, grupNo, siparisBilgi);
                sonTarih = DateTime.FromBinary(donenIsparcasi.BasTarihi.ToBinary());
                if (sonTarih < this.baslangicTarihi)
                {
                    //Geri yüklenemiyor
                    return null;
                }
                else
                {
                    //yüklemeye devam
                    if (op.AltParca.Count > 0)
                    {
                        Rota.OptimumSiralama siralama = (from x in siralamalar
                                                         where x.Ust == op
                                                         select x).FirstOrDefault();
                        IEnumerable<Rota.RotaParcasi> parcalar;
                        if (siralama != null)
                        {
                            parcalar = siralama.Siralama;
                        }
                        else
                        {
                            parcalar = op.AltParca;
                        }

                        foreach (Rota.RotaParcasi rp in parcalar)
                        {
                            DateTime? deger = OptimumYukle(rp, DateTime.FromBinary(sonTarih.ToBinary()), recDerinlik + 1, siralamalar);
                            if (deger.HasValue)
                            {
                                //Yüklendi
                                sonTarih = deger.Value;
                            }
                            else
                            {
                                //Yüklenemedi
                                return null;
                            }
                        }
                    }
                }
            }
            return sonTarih;
        }

        private List<Rota.RotaParcasi> temizle(List<Rota.RotaParcasi> gelenListe)
        {
            //Gelen rota listesinde operasyonu olmayanları listeden siler ve yeni listeye atar eski listeye dokunulmaz
            List<Rota.RotaParcasi> liste = new List<Rota.RotaParcasi>();
            foreach (Rota.RotaParcasi rp in gelenListe)
            {
                if (rp.OperasyonList.Count > 0)
                {
                    liste.Add(rp);
                }
            }
            return liste;
        }


        public void GeriAl()
        {
            cizelge.GeriAl(null, grupNo);
        }
    }
}